package security41.jwt.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.jwt.JwtClaimsSet;
import org.springframework.security.oauth2.jwt.JwtEncoder;
import org.springframework.security.oauth2.jwt.JwtEncoderParameters;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import security41.jwt.common.Results;
import security41.jwt.model.TUser;
import security41.jwt.service.TUserService;
import security41.jwt.vo.LoginVO;

import java.time.Instant;
import java.util.stream.Collectors;

@RestController
public class LoginController {

    @Autowired
    private JwtEncoder jwtEncoder;

    @Autowired
    private TUserService tUserService;


    @PostMapping("/login")
    public Results login(@RequestBody(required = false) LoginVO vo) {
        if (vo == null || vo.getUsername() == null || vo.getUsername().trim().length() <= 0) {
            return Results.res(500, "用户名参数不能为空", null);
        }
        if (vo.getPassword() == null || vo.getPassword().trim().length() <= 0) {
            return Results.res(500, "密码参数不能为空", null);
        }

        TUser user = tUserService.selectLoginUserInfoByUsername(vo.getUsername());
        if (user == null) {
            return Results.res(500, "登录失败，用户名或密码错误", null);
        }


        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        boolean matches = passwordEncoder.matches(vo.getPassword(), user.getPassword());
        if (!matches) {
            return Results.res(500, "登录失败，用户名或密码错误", null);
        }


        Instant now = Instant.now();
        //角色列表字符串，必须用空格分隔
        String scope = user.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.joining(" "));

        JwtClaimsSet claims = JwtClaimsSet.builder()
                .issuer("JWT")
                .issuedAt(now)
                .expiresAt(now.plusSeconds(TUserService.EXPIRY))
                .subject(user.getUsername())
                .claim("scope", scope)
                .build();
        //生成token
        String tokenValue = jwtEncoder.encode(JwtEncoderParameters.from(claims)).getTokenValue();

        Results results = new Results();
        results.setCode(200);
        results.setMsg("SUCCESS");
        results.setData(tokenValue);
        return results;
    }


}
